package com.boot.mgt.service.impl

import com.alibaba.fastjson.JSON
import com.boot.core.result.ResultEnum
import com.boot.core.result.ResultTo
import com.boot.core.util.ManagerKit
import com.boot.mgt.controller.web.vo.TaPoliceVo
import com.boot.mgt.dao.mysql.TaOndutyAccidentMapper
import com.boot.mgt.dao.mysql.TaOndutyMobileMapper
import com.boot.mgt.dao.mysql.TaPoliceMapper
import com.boot.mgt.model.TaOndutyAccident
import com.boot.mgt.model.TaOndutyMobile
import com.boot.mgt.model.TaPolice
import com.boot.mgt.service.TaPoliceService
import com.github.pagehelper.PageHelper
import com.github.pagehelper.PageInfo
import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImpl
import com.kawins.shiro.temp.util.PasswordUtil
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.jdbc.datasource.DriverManagerDataSource
import org.springframework.stereotype.Service
import tk.mybatis.mapper.entity.Example
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList


@AutoJsonRpcServiceImpl
@Service
class TaPoliceServiceImpl(
        @Value("\${conf.trafficTaskSource.url}") val url: String,
        @Value("\${conf.trafficTaskSource.username}") val name: String,
        @Value("\${conf.trafficTaskSource.password}") val pwd: String
) : TaPoliceService {

    @Value("\${conf.trafficTaskSource.url}")
    val a1: String = ""

    @Value("\${conf.trafficTaskSource.username}")
    val a2: String = ""

    @Value("\${conf.trafficTaskSource.password}")
    val a3: String = ""

    @Autowired
    protected lateinit var policeMapper: TaPoliceMapper

    @Autowired
    private lateinit var ondutyAccidentMapper: TaOndutyAccidentMapper

    @Autowired
    private lateinit var taOndutyMobileMapper: TaOndutyMobileMapper


    override fun getPoliceById(id: String): ResultTo {
        val taPolice = policeMapper.selectByPrimaryKey(id)
        return ResultTo().apply {
            this["police_info"] = taPolice
        }
    }

    override fun list(type: Int?, police_number: String?, name: String?, page_index: Int, page_size: Int, isAll: Boolean): ResultTo {
        if (!isAll && !(ManagerKit.isCaptain() || ManagerKit.isOutside())) {
            return ResultTo(ResultEnum.ILLEGAL_OPERATION)
        }

        val list = with(TaPolice()) {
            PageHelper.startPage<Any>(page_index, page_size)
            val example = Example(TaPolice::class.java)
            val createCriteria = example.createCriteria()
            createCriteria.andEqualTo("xqdw", ManagerKit.getOrgNum())
            if (isAll) {
                createCriteria.andLike("level", "1")
            }
            police_number?.let {
                createCriteria.andLike("policeNumber", "%$it%")
            }
            name?.let {
                createCriteria.andLike("name", "%$it%")
            }
            type?.let {
                createCriteria.andEqualTo("type", type)
            }
            policeMapper.selectByExample(example)
        }
        return ResultTo().apply {
            val pageInfo = PageInfo(list)
            this["police_list"] = list
            this["page_index"] = page_index
            this["page_amount"] = pageInfo.pages
            this["page_total"] = pageInfo.total
        }
    }

    override fun edit(policeVo: TaPoliceVo): ResultTo {
        log.info("收到数据:${JSON.toJSONString(policeVo)}")
        val police = policeVo as TaPolice
        police.xqdw = ManagerKit.getOrgNum()
        if (!ManagerKit.isCaptain()) {
            if (police.id == null || police.id != ManagerKit.getPoliceId()) {
                return ResultTo(ResultEnum.ILLEGAL_OPERATION)
            }
        }
        with(police) {
            if (id == null) {
                log.debug("ID为Null,新增警员操作")
                if (policeNumber.isNullOrBlank()) {
                    return ResultTo(ResultEnum.PARAM_ERROR)
                }
                val policeOne = TaPolice()
                policeOne.policeNumber = policeNumber
                if (policeMapper.selectCount(policeOne) > 0) {
                    log.info("警员编号{}已经存在", policeNumber)
                    return ResultTo(ResultEnum.POLICE_NUMBER_EXIST)
                }
                level = level ?: 1
                password = PasswordUtil.encryptPassword(this.password ?: "1234", TaPoliceService.DEF_SALT)
                addTime = Date()
                if (policeVo.level != 1) {
                    police.type = 0
                }
                policeMapper.insertSelective(police)
            } else {
                log.debug("ID不为Null,更新警员操作")
                password?.let {
                    val taPolice = policeMapper.selectByPrimaryKey(policeVo.id)
                    val oldPwd = PasswordUtil.encryptPassword(policeVo.oldPwd ?: "", TaPoliceService.DEF_SALT)
                    if (oldPwd != taPolice.password) {
                        return ResultTo(ResultEnum.OLD_PASSWORD_ERROR)
                    }
                    password = PasswordUtil.encryptPassword(it, TaPoliceService.DEF_SALT)
                    policeMapper.updateByPrimaryKeySelective(this)
                    return ResultTo()
                }
                addTime = null
                if (policeVo.level != 1) {
                    police.type = 0
                }
                policeMapper.updateByPrimaryKeySelective(police)
            }
        }
        return ResultTo()
    }

    override fun editRpc(policeVo: TaPoliceVo, police_level: Int, police_id: String, org_num: String): ResultTo {
        log.info("收到数据:${JSON.toJSONString(policeVo)}")
        val police = policeVo as TaPolice
        police.xqdw = org_num
        police.id = 1
        var result: MutableMap<String, Any> = searchPoliceById(police_id);
        //TODO: 为何加此判断,此判断和下方新增代码矛盾 by rankai
        if (result == null || result.isEmpty()) {
            return ResultTo(ResultEnum.USERNAME_ERROR)
        }
        if (police_level != 1) {
            if (police.id == null) {
                return ResultTo(ResultEnum.ILLEGAL_OPERATION)
            }
        }
        with(police) {
            //TODO: 此处新增无用 by rankai
            if (id == null) {
                log.debug("ID为Null,新增警员操作")
                if (policeNumber.isNullOrBlank()) {
                    return ResultTo(ResultEnum.PARAM_ERROR)
                }
                val policeOne = TaPolice()
                policeOne.policeNumber = policeNumber
                if (policeMapper.selectCount(policeOne) > 0) {
                    log.info("警员编号{}已经存在", policeNumber)
                    return ResultTo(ResultEnum.POLICE_NUMBER_EXIST)
                }
                level = level ?: 1
                password = PasswordUtil.encryptPassword(this.password ?: "1234", TaPoliceService.DEF_SALT)
                addTime = Date()
                if (policeVo.level != 1) {
                    police.type = 0
                }
                policeMapper.insertSelective(police)
            } else {
                log.debug("ID不为Null,更新警员操作")
                password?.let {
                    updatePoliceApp(police_id, LoginServiceImpl.generate(it)!!)
                    return ResultTo()
                }
                addTime = null
                if (policeVo.level != 1) {
                    police.type = 0
                }
                //TODO: 此处更新无用 by rankai
                policeMapper.updateByPrimaryKeySelective(police)
            }
        }
        return ResultTo()
    }

    override fun editNoOldPassword(policeVo: TaPoliceVo): ResultTo {
        log.info("收到数据:${JSON.toJSONString(policeVo)}")
        val police = policeVo as TaPolice
        police.xqdw = ManagerKit.getOrgNum()
        if (!ManagerKit.isCaptain()) {
            if (police.id == null || police.id != ManagerKit.getPoliceId()) {
                return ResultTo(ResultEnum.ILLEGAL_OPERATION)
            }
        }
        with(police) {
            if (id == null) {
                log.debug("ID为Null,新增警员操作")
                if (policeNumber.isNullOrBlank()) {
                    return ResultTo(ResultEnum.PARAM_ERROR)
                }
                val policeOne = TaPolice()
                policeOne.policeNumber = policeNumber
                if (policeMapper.selectCount(policeOne) > 0) {
                    log.info("警员编号{}已经存在", policeNumber)
                    return ResultTo(ResultEnum.POLICE_NUMBER_EXIST)
                }
                level = level ?: 1
                password = PasswordUtil.encryptPassword(this.password ?: "1234", TaPoliceService.DEF_SALT)
                addTime = Date()
                if (policeVo.level != 1) {
                    police.type = 0
                }
                policeMapper.insertSelective(police)
            } else {
                log.debug("ID不为Null,更新警员操作")
                password?.let {
                    password = PasswordUtil.encryptPassword(it, TaPoliceService.DEF_SALT)
                    policeMapper.updateByPrimaryKeySelective(this)
                    return ResultTo()
                }
                addTime = null
                if (policeVo.level != 1) {
                    police.type = 0
                }
                policeMapper.updateByPrimaryKeySelective(police)
            }
        }
        return ResultTo()
    }

    override fun selectScheduling(type: Int?, police_number: String?, start_time: Date?, end_time: Date?): ResultTo {

        if (type != null) {
            val orgNum = ManagerKit.getOrgNum()
            return if (type == 1) {
                val ondutyAccidents = ondutyAccidentMapper.selectAllWithPolice(police_number,
                        if (start_time == null) null else FORMAT.format(start_time),
                        if (end_time == null) null else FORMAT.format(end_time), orgNum)
                ondutyAccidents.forEach { r ->
                    var re: Map<String, Any> = searchPoliceById(r.policeNumber)
                    r.name = re.get("full_name") as String?
                    r.type = 1
                }
                ResultTo().setData("ondutyAccidents", ondutyAccidents)
                /*ResultTo().apply {
                    val pageInfo = PageInfo(ondutyAccidents)
                    this["police_list"] = ondutyAccidents
                    this["page_index"] = page_index
                    this["page_amount"] = pageInfo.pages
                    this["page_total"] = pageInfo.total
                }.setData("ondutyAccidents", ondutyAccidents)*/
            } else {
                val ondutyMobiles = taOndutyMobileMapper.selectAllWithPolice(police_number,
                        if (start_time == null) null else FORMAT.format(start_time),
                        if (end_time == null) null else FORMAT.format(end_time), orgNum)
                ondutyMobiles.forEach { r ->
                    var re: Map<String, Any> = searchPoliceById(r.policeNumber)
                    r.name = re["full_name"] as String?
                    r.type = 1
                }
                ResultTo().setData("taOndutyMobiles", ondutyMobiles)
            }
        } else if (!police_number!!.isBlank()) {
            TaPolice().apply {
                policeNumber = police_number
                policeMapper.selectOne(this)?.apply {
                    when {
                        this.type == 1 -> TaOndutyAccident().let {
                            it.policeNumber = this.policeNumber
                            it.xqdw = ManagerKit.getOrgNum()
                            val ondutyAccidents = ondutyAccidentMapper.select(it)
                            return ResultTo().setData("ondutyAccidents", ondutyAccidents)
                        }
                        this.type == 2 -> TaOndutyMobile().let {
                            it.policeNumber = this.policeNumber
                            it.xqdw = ManagerKit.getOrgNum()
                            val ondutyMobiles = taOndutyMobileMapper.select(it)
                            return ResultTo().setData("taOndutyMobiles", ondutyMobiles)
                        }
                        else -> return ResultTo(ResultEnum.OPERATION_FAILED, "您选的账号非警员角色")
                    }
                }
            }
        }
        return ResultTo(ResultEnum.ILLEGAL_OPERATION)
    }

    override fun scheduling(police_number: String, date: String): ResultTo {
        /*TaPolice().apply {
            policeNumber = police_number
            policeMapper.selectOne(this)?.apply {
                when {
                    this.type == 1 -> TaOndutyAccident().let {
                        it.attendedDate = date
                        //add by liuzhe @2019-02-23 增加一天多个值班员的支持
                        it.policeNumber = this.policeNumber
                        val ondutyAccident = ondutyAccidentMapper.selectOne(it)
                        if (ondutyAccident == null) {
                            it.addTime = Date()
                            it.attendedDate = date
                            it.policeNumber = police_number
                            it.xqdw = ManagerKit.getOrgNum()
                            ondutyAccidentMapper.insertSelective(it)
                        } else {
                            ondutyAccident.addTime = Date()
                            ondutyAccident.policeNumber = police_number
                            ondutyAccidentMapper.updateByPrimaryKeySelective(ondutyAccident)
                        }
                    }
                    this.type == 2 -> TaOndutyMobile().let {
                        it.attendedDate = date
                        val taOndutyMobile = taOndutyMobileMapper.selectOne(it)
                        if (taOndutyMobile == null) {
                            it.addTime = Date()
                            it.attendedDate = date
                            it.policeNumber = police_number
                            it.xqdw = ManagerKit.getOrgNum()
                            taOndutyMobileMapper.insertSelective(it)
                        } else {
                            taOndutyMobile.addTime = Date()
                            taOndutyMobile.policeNumber = police_number
                            taOndutyMobileMapper.updateByPrimaryKeySelective(taOndutyMobile)
                        }
                    }
                    else -> return ResultTo(ResultEnum.OPERATION_FAILED, "您选的账号非警员角色")
                }
            }
        }
        return ResultTo()
        */
        TaPolice().apply {
            policeNumber = police_number
            this?.apply {
                this.type = 1
                when {
                    this.type == 1 -> TaOndutyAccident().let {
                        it.attendedDate = date
                        //add by liuzhe @2019-02-23 增加一天多个值班员的支持
                        it.policeNumber = this.policeNumber
                        val ondutyAccident = ondutyAccidentMapper.selectOne(it)
                        if (ondutyAccident == null) {
                            it.addTime = Date()
                            it.attendedDate = date
                            it.policeNumber = police_number
                            it.xqdw = ManagerKit.getOrgNum()
                            ondutyAccidentMapper.insertSelective(it)
                        } else {
                            ondutyAccident.addTime = Date()
                            ondutyAccident.policeNumber = police_number
                            ondutyAccidentMapper.updateByPrimaryKeySelective(ondutyAccident)
                        }
                    }
                    this.type == 2 -> TaOndutyMobile().let {
                        it.attendedDate = date
                        val taOndutyMobile = taOndutyMobileMapper.selectOne(it)
                        if (taOndutyMobile == null) {
                            it.addTime = Date()
                            it.attendedDate = date
                            it.policeNumber = police_number
                            it.xqdw = ManagerKit.getOrgNum()
                            taOndutyMobileMapper.insertSelective(it)
                        } else {
                            taOndutyMobile.addTime = Date()
                            taOndutyMobile.policeNumber = police_number
                            taOndutyMobileMapper.updateByPrimaryKeySelective(taOndutyMobile)
                        }
                    }
                    else -> return ResultTo(ResultEnum.OPERATION_FAILED, "您选的账号非警员角色")
                }
            }
        }
        return ResultTo()
    }

    override fun searchAllPolice(police_number: String?): MutableList<MutableMap<String, Any>> {
        val dataSource = DriverManagerDataSource()
        dataSource.setDriverClassName("com.mysql.jdbc.Driver")
        dataSource.url = this.url
        dataSource.username = this.name
        dataSource.password = this.pwd
        var result: MutableList<MutableMap<String, Any>> = arrayListOf()
        try {
            val jdbcTemplate = JdbcTemplate(dataSource)
            result = jdbcTemplate.queryForList("select t.user_id, t.user_name, t.full_name, t.encrypted_password, t.region_id, t.group_id, t.empower, t.management from app_user t")
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return result

    }

    //TODO: 此处需要重构,不应使用JdbcTemplate
    override fun searchPoliceById(police_number: String?): MutableMap<String, Any> {
        val dataSource = DriverManagerDataSource()
        dataSource.setDriverClassName("com.mysql.jdbc.Driver")
        dataSource.url = this.url
        dataSource.username = this.name
        dataSource.password = this.pwd
        var result: MutableMap<String, Any> = mutableMapOf()
        try {
            val jdbcTemplate = JdbcTemplate(dataSource)
            result = jdbcTemplate.queryForMap("select t.user_id, t.user_name, t.full_name, t.encrypted_password, t.region_id, t.group_id, t.empower, t.management, ug.name, ug.role, ug.role_extend from app_user t left join user_group ug on ug.id=t.group_id where t.user_name= ? ", police_number)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return result
    }

    //TODO: 此处需要重构,不应使用JdbcTemplate
    override fun searchPoliceBySql(sql: String): List<MutableMap<String, Any>> {
        val dataSource = DriverManagerDataSource()
        dataSource.setDriverClassName("com.mysql.jdbc.Driver")
        dataSource.url = this.url
        dataSource.username = this.name
        dataSource.password = this.pwd
        var result: List<MutableMap<String, Any>> = arrayListOf()
        try {
            val jdbcTemplate = JdbcTemplate(dataSource)
            result = jdbcTemplate.queryForList(sql)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return result;
    }

    //TODO: 此处需要重构,不应使用JdbcTemplate且代码比较混乱
    override fun consRegion(regionId: String): String? {
        var regionSqlVal = ""
        val regionSql: String = " select rg.id, rg.name, rg.parent_id, rg.level from region_glbm rg where rg.id = '" + regionId + "' "
        val resultList = searchPoliceBySql(regionSql)
        if (resultList != null && resultList.isNotEmpty()) {
            val regionLevel = resultList[0]["level"]
            regionSqlVal = if (regionLevel == "1") {
                regionId.substring(0, 2) + "%"
            } else if (regionLevel == "2") {
                if ("6113" == regionId.substring(0, 4)) {
                    regionId.substring(0, 6) + "%"
                } else if ("6115" == regionId.substring(0, 4)) {
                    regionId.substring(0, 4) + "%"
                } else {
                    regionId.substring(0, 4) + "%"
                }
            } else {
                if ("6115" == regionId.substring(0, 10)) {
                    regionId.substring(0, 10) + "%"
                } else {
                    regionId.substring(0, 8) + "%"
                }
            }
        }
        return regionSqlVal
    }

    //TODO: 此处需要重构,不应使用JdbcTemplate
    override fun updatePoliceApp(police_number: String, newPassword: String): Any? {
        val dataSource = DriverManagerDataSource()
        dataSource.setDriverClassName("com.mysql.jdbc.Driver")
        dataSource.url = this.url
        dataSource.username = this.name
        dataSource.password = this.pwd
        var result = 0
        try {
            val jdbcTemplate = JdbcTemplate(dataSource)
            val updateSql = "update app_user t set t.encrypted_password=\"$newPassword\" where t.user_name=\"$police_number\""
            result = jdbcTemplate.update(updateSql)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return result
    }

    companion object {
        private val log: Logger = LoggerFactory.getLogger(this::class.java)
        private val FORMAT = SimpleDateFormat("yyyy-MM-dd")
    }

}